global._ = require('lodash')
global.APP_PATH = process.cwd()
global.path = require('path')
global.fs = require('fs')
global.configure = require('little-man-config')
global.pager = require('../../framework/lib/pager')
global.log4js = require('../../framework/lib/log4js')
global.helper = require('../../framework/lib/helper')
global.moment = require('moment')

const apiFree = require('api-free')                             // 载入api-free 核心组件

global.M = apiFree.M
global.DB = apiFree.DB
global.dbUtil = apiFree.dbUtil

// 载入app配置文件
const kong_cfg = configure.get('kong')
const service_config = kong_cfg.services;
const api_version_key = kong_cfg.api_version_key || 0;
const is_publish = kong_cfg.is_publish || 0;

const upstreamService = require('../../service/common/kong/upstream')
const targetService = require('../../service/common/kong/target')
const serviceService = require('../../service/common/kong/service')
const routeService = require('../../service/common/kong/route')
const pluginService = require('../../service/common/kong/plugin')

// 遍历sys_app表，向kong 同步消费者
async function scan (args = {}) {
    let services = service_config
    // 查找消费者
    for (let i = 0; i < services.length; i++) {
        let item = services[i]

        await _scanItem({...item})
    }

    return true
}

async function _scanItem (item = {}) {
    log4js.debug('开始添加upstream ', item.name)
    let _upstream_add = await upstreamService.put(api_version_key ? `${api_version_key}.${item.name}` : item.name, {
        name: api_version_key ? `${api_version_key}.${item.name}` : item.name,
        hash_on: 'ip',
        healthchecks: {
            active: {
                unhealthy: {
                    tcp_failures: 2,
                    timeouts: 10,
                    http_failures: 2,
                    interval: 3,
                },
                http_path: '/',
                timeout: 10,
                healthy: {
                    interval: 3,
                    successes: 1,
                }
            },
            passive: {
                unhealthy: {
                    http_failures: 2,
                    tcp_failures: 2,
                    timeouts: 10,
                },
                healthy: {
                    successes: 1,
                }
            }
        }
    })

    log4js.debug('添加upstream, 结果:', _upstream_add && !!_upstream_add.id)

    if (_upstream_add && !!_upstream_add.id) {
        let _list_all_target = await targetService.list(_upstream_add.name)

        let _targets = _.get(_list_all_target, 'data', [])
        let _item_targets = item.targets.map(m => ({ target: m[0], weight: m[1] }))

        // 删除多余的target
        await Promise.all(_targets.filter(f => !(_item_targets.map(m => m.target).includes(f.target))).map(async (_t) => {
            await targetService.delete(_upstream_add.id, _t.id)
            log4js.debug('删除多余的target ', _upstream_add.name, _t.target)
        }))

        log4js.debug('开始处理targets: ')
        for (let i = 0; i < _item_targets.length; i++) {
            let _this_item_target = _item_targets[i]
            let _target_index = _targets.findIndex(f => f.target === _this_item_target.target)
            if (!!~_target_index) {
                if (_this_item_target.weight !== _.get(_targets, `${_target_index}.weight`)) {
                    // 权重不同，删除重新创建
                    await targetService.delete(_upstream_add.name, _this_item_target.target)
                    let _re_add_target = await targetService.add(_upstream_add.name, {
                        target: _this_item_target.target,
                        weight: _this_item_target.weight,
                    })
                    log4js.debug('权重不同，删除重新创建, 结果 ', _re_add_target && !!_re_add_target.target)
                } else {
                    log4js.debug('target 已存在，不处理', _this_item_target.target, _this_item_target.weight)
                }
            } else {
                // 直接添加
                log4js.debug('直接添加 target', _this_item_target.target, _this_item_target.weight)
                let _add_target = await targetService.add(_upstream_add.name, {
                    target: _this_item_target.target,
                    weight: _this_item_target.weight,
                })
                log4js.debug('直接添加 target, 结果 ', _add_target && !!_add_target.target)
            }
        }

        // 添加服务
        let _add_service = await serviceService.put(_upstream_add.name, {
            name: _upstream_add.name,
            host: _upstream_add.name,
            port: 80,
        })

        log4js.debug('添加service: ', _add_service && !!_add_service.id)

        let _get_route = await routeService.get(_upstream_add.name)
        log4js.debug('添加路由: ', _get_route && !!_get_route.id)
        if (_get_route && !!_get_route.id) {
            let _update_route = await routeService.patch(_get_route.id, {
                name: _upstream_add.name,
                paths: [`/${item.name}`],
                headers: api_version_key && !is_publish ? {'x-api-version-key': [`${api_version_key}`]} : {}
            })
            log4js.debug('已存在，更新: ', _update_route && !!_update_route.id)
        } else {
            let _add_service_route = await routeService.add_service_route({
                name: _upstream_add.name,
                paths: [`/${item.name}`],
                headers: api_version_key && !is_publish ? {'x-api-version-key': [`${api_version_key}`]} : {}
            }, _upstream_add.name)
            log4js.debug('不存在，创建: ', _add_service_route && !!_add_service_route.id)
        }

        if (!!item.websocket) {
            // 处理websocket 路由
            let _get_ws_route = await routeService.get(`${_upstream_add.name}.websocket`)
            log4js.debug('添加ws路由: ', _get_ws_route && !!_get_ws_route.id)
            if (_get_ws_route && !!_get_ws_route.id) {
                let _update_ws_route = await routeService.patch(_get_ws_route.id, {
                    name: `${_upstream_add.name}.websocket`,
                    paths: [`/socket.io`],
                })
                log4js.debug('ws 已存在，更新: ', _update_ws_route && !!_update_ws_route.id)
            } else {
                let _add_service_ws_route = await routeService.add_service_route({
                    name: `${_upstream_add.name}.websocket`,
                    paths: [`/socket.io`]
                }, _upstream_add.name)
                log4js.debug('不存在，创建: ', _add_service_ws_route && !!_add_service_ws_route.id)
            }
        }

        // 初始化插件

        let _plugins = await pluginService.list(_add_service.id)
        _plugins = _.get(_plugins, 'data') || []

        if (!_.isEmpty(item.plugin)) {
            let _keys = _.keys(item.plugin);

            for(let _i=0;_i<_keys.length;_i++) {
                let _plugin = _keys[_i];

                let _args = item.plugin[_plugin] || {}
                if (_plugin === 'jwt') { // 默认参数
                    _args = Object.assign({}, {
                        enabled: true,
                        config: {
                            uri_param_names: ['jwt'],
                            cookie_names: ['jwt'],
                            key_claim_name: 'iss',
                            secret_is_base64: false,
                            run_on_preflight: true,
                            claims_to_verify: null,
                            maximum_expiration: 0,
                            header_names: ['Authorization', 'X-Consumer-Username'],
                        }
                    }, _args)
                } else if (_plugin === 'cors') { //  默认参数
                    _args = Object.assign({}, {
                        enabled: true,
                        config: {
                            origins: ['*'],
                            methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'],
                        }
                    }, _args)
                } else if (_plugin === 'response-transformer') { //  默认参数
                    _args = Object.assign({}, {
                        enabled: true,
                        config: {
                            add: {
                                json: ['errno:10000']
                            },

                        }
                    }, _args)
                }

                let _index = _plugins.findIndex(f => f.name === _plugin)
                let plugAddRet
                if (!!~_index) {
                    plugAddRet = await pluginService.update(_plugins[_index].id, {
                        ..._args,
                        name: _plugin,
                    })
                } else {
                    plugAddRet = await pluginService.add(_add_service.id, {
                        ..._args,
                        name: _plugin,
                    })
                }

                log4js.debug(`创建插件 ${_plugin}, 结果: ${plugAddRet && !!plugAddRet.id}`)
            }
        }

        log4js.debug('服务注册成功: ', _upstream_add.name)
    }
}

// 初始化 api-free
apiFree.init(configure.get('apifree')).then(async ()=>{
    await scan()
    log4js.debug('DONE')
    process.exit(0)
}).catch(err => {
    log4js.error(err)
})



